package top.scauwlt.spring;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.stereotype.Component;
import top.scauwlt.annotation.RpcScan;
import top.scauwlt.annotation.RpcService;

import java.util.Map;
import java.util.Set;

/**
 * @Author wmm
 * @Date 2022/7/27 16:35
 */
@Slf4j
public class CustomScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
    private static final String SPRING_BEAN_BASE_PACKAGE = "top.scauwlt";
    private static final String BASE_PACKAGE_ATTRIBUTE_NAME = "basePackage";
    private ResourceLoader resourceLoader;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        //获取被@RpcScan注解的类，返回一个Map，装着注解的属性值 eg：("basePackage": "top.scauwlt" ...)
        Map<String, Object> map = annotationMetadata.getAnnotationAttributes(RpcScan.class.getName());
        //这里转换一下，方便操作，AnnotationAttributes是LinkedHashMap的子类
        AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(map);
        String[] rpcScanBasePackages = new String[0];
        if (annotationAttributes != null) {
            //获取到所有包路径 eg:top.scauwlt
            rpcScanBasePackages = annotationAttributes.getStringArray(BASE_PACKAGE_ATTRIBUTE_NAME);
        }
        if (rpcScanBasePackages.length == 0) {
            rpcScanBasePackages = new String[]{((StandardAnnotationMetadata) annotationMetadata).getIntrospectedClass().getPackage().getName()};
        }
        log.info("rpcScanBasePackages : [{}]", rpcScanBasePackages);
        CustomScanner rpcServiceScanner = new CustomScanner(beanDefinitionRegistry, RpcService.class);
        CustomScanner springBeanScanner = new CustomScanner(beanDefinitionRegistry, Component.class);
        if (resourceLoader != null) {
            rpcServiceScanner.setResourceLoader(resourceLoader);
            springBeanScanner.setResourceLoader(resourceLoader);
        }

        int rpcServiceScanAmount = rpcServiceScanner.scan(rpcScanBasePackages);
        log.info("Scan rpc service amount: {}", rpcServiceScanAmount);

        int springBeanScanAmount = springBeanScanner.scan(rpcScanBasePackages);
        log.info("Scan spring bean amount: {}", springBeanScanAmount);

        //这里RpcReference不用扫描，因为是注解在属性上的
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}
